package controllers

import (
	"encoding/json"
	"errors"
	"strings"

	md "gitee.com/countpoison/youbei/models"
	utils "gitee.com/countpoison/youbei/utils"
	db "gitee.com/countpoison/youbei/utils/database"
	jobs "gitee.com/countpoison/youbei/utils/jobs"

	"github.com/beego/beego/v2/adapter/toolbox"
	"github.com/segmentio/ksuid"
)

// Tasklist ...
func (c *MainController) Tasklist() {
	types := c.GetString("types")
	page, _ := c.GetInt("page")
	count, _ := c.GetInt("count")
	tasks, err := md.SelectAll(types, page, count)
	c.APIReturn(500, "获取列表失败", err)
	title, err := md.TaskCount(types)
	c.APIReturn(500, "获取总数失败", err)
	rep := map[string]interface{}{"count": title, "data": tasks}
	c.APIReturn(200, "获取列表成功", &rep)
}

// GetTask ...
func (c *MainController) GetTask() {
	id := c.Ctx.Input.Param(":id")
	task := new(md.Task)
	task.ID = id
	c.APIReturn(500, "获取数据失败", task.Select())
	c.APIReturn(200, "获取数据成功", task)
}

// Del ...
func (c *MainController) Del() {
	ob := new(md.Task)
	ob.ID = c.Ctx.Input.Param(":id")
	c.APIReturn(500, "删除任务失败1", ob.Delete())
	toolbox.DeleteTask(ob.ID)
	c.APIReturn(200, "删除任务成功", c.Ctx.Input.Param(":id"))
}

// Add ...
func (c *MainController) Add() {
	ob := new(md.Task)
	c.APIReturn(500, "解析数据失败", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	if ob.Crontab == "" {
		c.APIReturn(500, "计划任务必填", errors.New("计划任务必填"))
	}
	ob.DBpath = strings.Replace(ob.DBpath, "\\", "/", -1)
	if ob.DBType == "mysql" {
		for _, v := range ob.DBnames {
			c.APIReturn(500, "添加任务失败mysql", db.MysqlConnectTest(ob.Host, ob.Port, v, ob.User, ob.Password, ob.Char))
			ob.DBname = v
			if err := c.submitTask(ob); err != nil {
				c.APIReturn(500, "添加任务失败", err)
			}
		}
		c.APIReturn(200, "添加任务成功", nil)
	} else if ob.DBType == "mssql" {
		c.APIReturn(500, "添加任务失败mssql", db.MssqlConnectTest(ob.Host, ob.DBname, ob.User, ob.Password))

	} else if ob.DBType == "sqlite" {
		c.APIReturn(500, "添加任务失败sqlite", db.SqliteConnectTest(ob.DBpath))

	} else if ob.DBType == "postgres" {
		c.APIReturn(500, "添加任务失败pgsql", db.PostgresConnectTest(ob.Host, ob.Port, ob.DBname, ob.User, ob.Password))

	} else if ob.DBType == "file" {
		bol, err := utils.PathExists(ob.DBpath)
		c.APIReturn(500, "file not found 1", err)
		if !bol {
			c.APIReturn(500, "file not found", errors.New("file not found"))
		}
	} else {
		c.APIReturn(500, "没有此类型数据", errors.New("dbtype not found"))
	}
	if err := c.submitTask(ob); err != nil {
		c.APIReturn(500, "添加任务失败", err)
	}
	c.APIReturn(200, "添加任务成功", nil)
}

func (c *MainController) submitTask(ob *md.Task) error {
	ob.ID = ksuid.New().String()
	ob.Pause = "no"
	if len(ob.RS) > 0 {
		if err := md.RemoteStorageToTaskFunc(ob.ID, ob.RS); err != nil {
			return err
		}
	}
	if err := ob.Add(); err != nil {
		return err
	}
	toolbox.AddTask(ob.ID, toolbox.NewTask(ob.ID, ob.Crontab, jobs.Jobs(ob.ID)))
	return nil
}

// Update ...
func (c *MainController) Update() {
	ob := new(md.Task)
	c.APIReturn(500, "更新任务失败1", json.Unmarshal(c.Ctx.Input.RequestBody, ob))
	if ob.Crontab == "" {
		c.APIReturn(500, "计划任务必填", errors.New("计划任务必填"))
	}
	if ob.DBType == "mysql" {
		c.APIReturn(500, "更新任务失败4", db.MysqlConnectTest(ob.Host, ob.Port, ob.DBname, ob.User, ob.Password, ob.Char))
	} else if ob.DBType == "mssql" {
		c.APIReturn(500, "更新任务失败4", db.MssqlConnectTest(ob.Host, ob.DBname, ob.User, ob.Password))
	} else if ob.DBType == "sqlite" {
		c.APIReturn(500, "更新任务失败4", db.SqliteConnectTest(ob.DBpath))
	} else if ob.DBType == "file" {
		bol, err := utils.PathExists(ob.DBpath)
		c.APIReturn(500, "file not found 1", err)
		if !bol {
			c.APIReturn(500, "file not found", errors.New("file not found"))
		}
	} else {
		c.APIReturn(500, "没有此类型数据", errors.New("dbtype not found"))
	}

	if len(ob.RS) > 0 {
		c.APIReturn(500, "更新任务失败6", md.RemoteStorageToTaskFunc(ob.ID, ob.RS))
	}
	c.APIReturn(500, "更新任务失败2", ob.Update())
	toolbox.AddTask(ob.ID, toolbox.NewTask(ob.ID, ob.Crontab, jobs.Jobs(ob.ID)))
	c.APIReturn(200, "更新任务成功", ob.ID)
}
